//
//  SEGuideDiagnosisInfoViewController.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/8.
//

import UIKit
import Photos

class SEGuideDiagnosisInfoViewController: SEBaseViewController {
    
    private var viewModel = SEInquiryInfoViewModel(withLoading: true) {
        didSet {
            tableView.reloadData()
        }
    }
    private var uploadVM = SEUploadViewModel(withLoading: true)
    
    @IBOutlet private weak var confirmViewHeightConstraint: NSLayoutConstraint!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        viewModel.confirmGuideDiagnosisInfoSuccess = { [weak self] status in
            switch status {
            case .success:
                self?.pushToChatVc()
            case .auth:
                self?.presentLoginViewController(selector: nil)
            case .failure:
                break
            }
        }
        
        uploadVM.updateData = { [weak self] status in
            guard let model = self?.uploadVM.fileModel else { return }
            switch status {
            case .success:
                self?.viewModel.addImage(with: model)
                self?.tableView.reloadData()
            case .auth:
                self?.presentLoginViewController(selector: nil)
            case .failure: break
            }
        }
    }
    
    override func setupUI() {
        super.setupUI()
        
        confirmView.agreeClosure = { [weak self] isAgree in
            guard let self = self else { return }
            self.viewModel.isAgree = isAgree
            if isAgree {
                self.confirmViewHeightConstraint.constant -= 195
                UIView.animateKeyframes(withDuration: 0.25, delay: 0, options: .calculationModeLinear) {
                    self.confirmView.updateUI(true)
                    self.view.layoutIfNeeded()
                }
            } else {
                self.confirmViewHeightConstraint.constant += 195
                UIView.animateKeyframes(withDuration: 0.25, delay: 0, options: .calculationModeLinear) {
                    self.view.layoutIfNeeded()
                } completion: { _ in
                    self.confirmView.updateUI(false)
                }
            }
        }
        
        confirmView.confirmClosure = { [weak self] in
            if self?.checkPatientConditionDidFillin() == true {
                self?.viewModel.confirmGuideDiagnosisInfo()
            }
        }
    }
    
    func pushToChatVc() {
        let chatVc = SEChatViewController(infoViewModel: viewModel, isFirstLoad: true)
        chatVc.title = "正在咨询..."
        removeCurrentVcWhenPush(chatVc)
    }

    @IBOutlet private weak var tableView: UITableView! {
        didSet {
            tableView.backgroundColor = .background
            tableView.tableFooterView = UIView()
            tableView.keyboardDismissMode = .onDrag
            
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
            tapGesture.cancelsTouchesInView = false
            tableView.addGestureRecognizer(tapGesture)
            
            tableView.register(SEGuideDiagnosisInfoDescCell.nibForCell(),
                               forCellReuseIdentifier: SEGuideDiagnosisInfoDescCell.reuseIdentifier())
            tableView.register(SEOnlineReserveAllergyHistoryCell.nibForCell(),
                               forCellReuseIdentifier: SEOnlineReserveAllergyHistoryCell.reuseIdentifier())
            tableView.register(SEOnlineReserveImageCell.nibForCell(),
                               forCellReuseIdentifier: SEOnlineReserveImageCell.reuseIdentifier())
        }
    }
    
    @IBOutlet private weak var confirmView: SEGuideDiagnosisInfoConfirmView! {
        didSet {
            confirmView.setLayerCorners(rect: confirmView.bounds,
                                        radius: 16,
                                        corners: [.topLeft, .topRight])
            confirmView.setShadow()
        }
    }
    
    @objc private func dismissKeyboard() {
        tableView.endEditing(true)
    }
}

extension SEGuideDiagnosisInfoViewController {
    private func checkPatientConditionDidFillin() -> Bool {
        if !viewModel.isAgree {
            SEHUD.show(message: "请确认已阅读并知晓了以上内容")
            return false
        }
        if viewModel.conditionDescEmpty {
            SEHUD.show(message: "病情描述没填")
            return false
        }
        if viewModel.allergyHistoryEmpty {
            SEHUD.show(message: "过敏史没填")
            return false
        }
        return true
    }
}

// MARK: - UITableViewDataSource

extension SEGuideDiagnosisInfoViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return viewModel.numberOfSectionsForGuideDiagnosisInfo
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch indexPath.section {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEGuideDiagnosisInfoDescCell.reuseIdentifier()) as! SEGuideDiagnosisInfoDescCell
            cell.update(with: viewModel) { viewModel in
                self.viewModel = viewModel
            }
            return cell
        case 1:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEOnlineReserveAllergyHistoryCell.reuseIdentifier()) as! SEOnlineReserveAllergyHistoryCell
            cell.update(with: viewModel, editEable: true) { viewModel in
                self.viewModel = viewModel
            }
            return cell
        case 2:
            let cell = tableView.dequeueReusableCell(withIdentifier: SEOnlineReserveImageCell.reuseIdentifier()) as! SEOnlineReserveImageCell
            cell.delegate = self
            cell.update(with: viewModel)
            return cell
        default:
            return UITableViewCell()
        }
    }
}

// MARK: - SEOnlineReserveImageCellDelegate

extension SEGuideDiagnosisInfoViewController: SEOnlineReserveImageCellDelegate {
    func imageCell(_ cell: SEOnlineReserveImageCell, toImagePickerWith viewModel: SEInquiryInfoViewModel) {
        if viewModel.conditionDescEmpty {
            SEHUD.show(message: "请先填写病情描述")
            return
        }
        if viewModel.allergyHistoryEmpty {
            SEHUD.show(message: "请先填写过敏史")
            return
        }
        
        SEAlert.showImagePickerSheet(in: self) { _ in
            self.checkCameraPermission()
        } photoHandler: { _ in
            self.openPhotoLibrary()
        }
    }
    
    func imageCell(_ cell: SEOnlineReserveImageCell, deleteImageWith viewModel: SEInquiryInfoViewModel) {
        self.viewModel = viewModel
    }
}

// MARK: - UIImagePickerControllerDelegate

extension SEGuideDiagnosisInfoViewController {
    private func checkCameraPermission() {
        let authStatus = AVCaptureDevice.authorizationStatus(for: .video)
        switch authStatus {
        case .notDetermined:
            AVCaptureDevice.requestAccess(for: .video) { (granted) in
                if !granted {
                    dispatch_async_safely_main_queue {
                        SEAlert.show(in: self.navigationController,
                                     title: "无法访问您的相机",
                                     message: "请到设置 -> 隐私 -> 相机 ，打开访问权限",
                                     confirmTitle: "去设置") { _ in
                            SEOpenSettingURL()
                        }
                    }
                }
            }
        case .restricted, .denied:
            SEAlert.show(in: self.navigationController,
                         title: "无法访问您的相机",
                         message: "请到设置 -> 隐私 -> 相机 ，打开访问权限",
                         confirmTitle: "去设置") { _ in
                SEOpenSettingURL()
            }
        case .authorized:
            openCamera()
        default:
            break
        }
    }
    
    private func openCamera() {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        present(imagePicker, animated: true, completion: nil)
    }
    
    private func openPhotoLibrary() {
        UIScrollView.appearance().contentInsetAdjustmentBehavior = .automatic
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .photoLibrary
        imagePicker.modalPresentationStyle = .custom
        present(imagePicker, animated: true, completion: nil)
    }
}

extension SEGuideDiagnosisInfoViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            uploadVM.uploadImage(bucket: "A", type: "A-9", image: image, size: image.imageSize())
        }
        dismiss(animated: true) {
            UIScrollView.appearance().contentInsetAdjustmentBehavior = .never
        }
    }
}

// MARK: - UITableViewDelegate

extension SEGuideDiagnosisInfoViewController: UITableViewDelegate {
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        if section == 1 {
            let header = UINib.loadViewFrom(SEAllergyHistoryHeader.self)
            header.update(with: viewModel) { viewModel in
                self.viewModel = viewModel
            }
            return header
        }
        return nil
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return viewModel.cellHeightForGuideDiagnosisInfo(at: indexPath)
    }
    
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        switch section {
        case 0:  return 1
        case 1:  return 45
        default: return 10
        }
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return section == 0 ? 10 : 0.001
    }
}
